import { dom, Nodes } from '@knno/dom';
import { maskStyle } from './mask.css';
import type { Property } from 'csstype';

export const DragMask = {
	show(
		evt: PointerEvent,
		cursor: Property.Cursor,
		onmove: (evt: PointerEvent, distance: { x: number; y: number }) => void,
		onclose?: (evt: PointerEvent) => void
	) {
		const startX = evt.clientX;
		const startY = evt.clientY;
		evt.preventDefault();
		evt.stopPropagation();
		const pointerId = evt.pointerId;
		const mask = dom.div(maskStyle, 'drag').css('cursor', cursor).appendTo(document.body);
		mask.elems()[0].setPointerCapture(pointerId);
		mask.on('pointermove', move);
		mask.on('pointercancel', (ev) => {
			close(ev);
		});
		mask.on('pointerup', (ev) => {
			close(ev);
		});
		function move(evt: PointerEvent) {
			if (evt.pointerId === pointerId) {
				evt.preventDefault();
				evt.stopPropagation();
				onmove(evt, { x: evt.clientX - startX, y: evt.clientY - startY });
			}
		}
		function close(ev: PointerEvent) {
			if (ev.pointerId === pointerId) {
				mask.elems()[0].releasePointerCapture(evt.pointerId);
				mask.detach();
				onclose?.(ev);
			}
		}
		return mask;
	},
};

let ref = 0;
let mask: Nodes | null = null;

export const Mask = {
	show() {
		if (ref === 0) {
			mask = dom.div(maskStyle, 'mask').appendTo(document.body);
			setTimeout(() => {
				mask?.addClass('active');
			}, 16);
		}
		ref++;
	},
	close() {
		if (ref > 0) {
			ref--;
			if (ref === 0 && mask) {
				const m = mask;
				mask.removeClass('active');
				setTimeout(() => {
					m.detach();
					if (ref <= 0) {
						mask = null;
					}
				}, 200);
			}
		}
	},
};
